package com.ssrs.platform.controller;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ssrs.framework.User;
import com.ssrs.framework.security.annotation.Priv;
import com.ssrs.framework.util.DataConvertUtil;
import com.ssrs.framework.web.ApiResponses;
import com.ssrs.framework.web.BaseController;
import com.ssrs.platform.code.MessageType;
import com.ssrs.platform.code.YesOrNoNumber;
import com.ssrs.platform.extend.IMessageType;
import com.ssrs.platform.extend.MessageTypeService;
import com.ssrs.platform.extend.item.DefaultMessage;
import com.ssrs.platform.model.entity.Message;
import com.ssrs.platform.model.entity.UserRole;
import com.ssrs.platform.model.query.AllUserDataBindQuery;
import com.ssrs.platform.service.IMessageService;
import com.ssrs.platform.service.IUserRoleService;
import com.ssrs.platform.util.Page;
import com.ssrs.platform.util.PlatformUtil;
import com.ssrs.platform.util.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 * @author ssrs
 * @since 2020-11-15
 */
@RestController
@RequestMapping("/api/message")
public class MessageController extends BaseController {

    @Autowired
    private IMessageService messageService;

    @Autowired
    private IUserRoleService userRoleService;


    /**
     * 获取消息类型列表
     * @return
     */
    @GetMapping("/getMessageTypeList")
    @Priv
    public ApiResponses<List<Map<String, String>>> getMessageTypeList() {
        List<Map<String, String>> list = new ArrayList<>();
        List<IMessageType> messageTypeList = MessageTypeService.getInstance().getAll();
        for (IMessageType iMessageType : messageTypeList) {
            Map<String, String> map = new HashMap<>();
            map.put("label", iMessageType.getExtendItemName());
            map.put("value", iMessageType.getExtendItemId());
            list.add(map);
        }
        return success(list);
    }

    /**
     * 获取消息子类型列表
     * @return
     */
    @GetMapping("/getMessageSubTypeList")
    @Priv
    public ApiResponses<List<Map<String, String>>> getSubTypeList() {
        return success(PlatformUtil.getCodeList(MessageType.CODETYPE));
    }

    /**
     * 获取未读消息数量
     * @return
     */
    @GetMapping("/count")
    @Priv
    public ApiResponses<Integer> count() {
        int count = messageService.count(Wrappers.<Message>lambdaQuery()
                .eq(Message::getToUser, User.getUserName())
                .eq(Message::getReadFlag, 0)
                .eq(Message::getDelByToUser, 0)
                .eq(Message::getDelByFromUser, 0));
        return success(count);
    }

    @Priv
    @PostMapping
    public ApiResponses<String> create(String toUser, String toRole, String subject, String content) {
        if (StrUtil.isEmpty(toUser) && StrUtil.isEmpty(toRole)) {
            return failure("接收人与接收角色不能都为空！");
        }
        List<String> userList = new ArrayList<>();

        if (StrUtil.isNotEmpty(toUser)) {
            String[] array = StrUtil.isEmpty(toUser) ? new String[]{} : toUser.split(",");
            userList = CollUtil.distinct(Arrays.stream(array).map(p -> String.valueOf(p)).collect(Collectors.toSet()));
        }
        if (StrUtil.isNotEmpty(toRole)) {
            List<UserRole> userRoles = userRoleService.list(Wrappers.<UserRole>lambdaQuery().in(UserRole::getRoleCode, toRole.split(",")));
            Set<String> userNames = userRoles.stream().map(UserRole::getUserName).collect(Collectors.toSet());
            for (String userName : userNames) {
                if (!userList.contains(userName)) {
                    userList.add(userName);
                }
            }
        }
        List<Message> saveList = new ArrayList<>();
        for (String userName : userList) {
            Message message = new Message();
            message.setSubject(subject);
            message.setBox("outbox"); // 默认信箱
            message.setContent(content);
            message.setFormUser(User.getUserName());
            message.setToUser(userName);
            message.setReadFlag(Convert.toInt(YesOrNoNumber.NO));
            message.setDelByFromUser(Convert.toInt(YesOrNoNumber.NO));
            message.setDelByToUser(Convert.toInt(YesOrNoNumber.NO));
            message.setPopFlag(Convert.toInt(YesOrNoNumber.NO));
            message.setType(DefaultMessage.ID);
            message.setSubType(MessageType.USER_SEND);
            saveList.add(message);
        }
        messageService.saveBatch(saveList);
        return success("发送成功！");
    }

    @GetMapping("/{id}")
    @Priv
    public ApiResponses<Message> detail(@PathVariable Long id) {
        Message message = messageService.getById(id);
        return success(message);
    }

    @GetMapping
    @Priv
    public ApiResponses<Page> list(@RequestParam Map<String, Object> paramas) {
        String type = Convert.toStr(paramas.get("type"));
        String subType = Convert.toStr(paramas.get("subType"));
        String readFlag = Convert.toStr(paramas.get("readFlag"));
        String subject = Convert.toStr(paramas.get("subject"));
        String formUser = Convert.toStr(paramas.get("formUser"));
        IPage<Message> ipage = messageService.page(new Query<Message>().getPage(paramas, Message.CREATE_TIME, false), Wrappers.<Message>lambdaQuery()
                .select(Message.class, info -> !info.getColumn().equals(Message.CONTENT))
                .eq(Message::getToUser, User.getUserName())
                .ne(Message::getDelByToUser, Convert.toInt(YesOrNoNumber.YES))
                .eq(StrUtil.isNotEmpty(subType), Message::getSubType, subType)
                .eq(StrUtil.isNotEmpty(readFlag), Message::getReadFlag, readFlag)
                .like(StrUtil.isNotEmpty(subject), Message::getSubject, subject)
                .like(StrUtil.isNotEmpty(formUser), Message::getFormUser, formUser)
                .eq(StrUtil.isNotEmpty(type), Message::getType, type));

        Page page = new Page(ipage);

        List<?> data = page.getData();
        List list = PlatformUtil.decodeByCodeType(data, MessageType.CODETYPE, "subType");
        page.setData(list);
        return success(page);
    }


    @GetMapping("/alluserdatabind")
    @Priv
    public ApiResponses<Page> alluserdatabind(@RequestParam Map<String, Object> paramas) {
        String selectedUser = Convert.toStr(paramas.get("selectedUser"));
        if (StrUtil.isNotEmpty(selectedUser)) {
            paramas.put("selectedUser", selectedUser.split(","));
        }
        IPage<AllUserDataBindQuery> ipage = messageService.alluserdatabind((com.baomidou.mybatisplus.extension.plugins.pagination.Page<AllUserDataBindQuery>) new Query<AllUserDataBindQuery>().getPage(paramas), paramas);
        Page page = new Page(ipage);
        return success(page);
    }


    @GetMapping("selecteduserdatabind")
    @Priv
    public ApiResponses<List<AllUserDataBindQuery>> selecteduserdatabind(@RequestParam Map<String, Object> paramas) {
        String selectedUser = Convert.toStr(paramas.get("selectedUser"));
        if (StrUtil.isNotEmpty(selectedUser)) {
            paramas.put("selectedUser", selectedUser.split(","));
        }
        if (StrUtil.isNotEmpty(selectedUser)) {
            List<AllUserDataBindQuery> list = messageService.selecteduserdatabind(paramas);
            return success(list);
        } else {
            return success(new ArrayList<>());
        }

    }

    /**
     * 标记为已读
     */
    @Priv
    @PutMapping("/{ids}/setreadflag")
    public ApiResponses<String> setReadFlag(@PathVariable String ids) {
        List<Long> idList = DataConvertUtil.arryToLongUniqueList(ids);
        messageService.update(new Message(), Wrappers.<Message>lambdaUpdate().set(Message::getReadFlag, YesOrNoNumber.YES).in(Message::getId, idList));
        return success("操作成功");
    }

    /**
     * 标记为已读
     */
    @Priv
    @DeleteMapping("/del/{ids}/{userType}")
    public ApiResponses<String> setReadFlag(@PathVariable String ids, @PathVariable String userType) {
        List<Long> idList = DataConvertUtil.arryToLongUniqueList(ids);
        if ("fromUser".equals(userType)) {
            messageService.update(new Message(), Wrappers.<Message>lambdaUpdate()
                    .set(Message::getDelByFromUser, YesOrNoNumber.YES)
                    .in(Message::getId, idList));
        } else if ("toUser".equals(userType)) {
            messageService.update(new Message(), Wrappers.<Message>lambdaUpdate()
                    .set(Message::getReadFlag, YesOrNoNumber.YES)
                    .set(Message::getDelByToUser, YesOrNoNumber.YES)
                    .in(Message::getId, idList));
        }
        return success("操作成功");
    }

    /**
     * 获取历史消息数据
     * @return
     */
    @Priv
    @GetMapping("/sendlist")
    public ApiResponses<Page> historyDataBind(@RequestParam Map<String, Object> params) {
        IPage<Message> ipage = messageService.page(new Query<Message>().getPage(params, Message.CREATE_TIME, false), Wrappers.<Message>lambdaQuery()
                .eq(Message::getFormUser, User.getUserName())
                .ne(Message::getDelByFromUser, Convert.toInt(YesOrNoNumber.YES))
                .eq(Message::getType, DefaultMessage.ID));

        Page page = new Page(ipage);
        return success(page);
    }


    /**
     * 消息回复
     */
    @Priv
    @PostMapping("/reply")
    public ApiResponses<String> reply(String toUser, String subject, String content) {
        Message message = new Message();
        message.setSubject(subject);
        message.setBox("outbox"); // 默认信箱
        message.setContent(content);
        message.setFormUser(User.getUserName());
        message.setToUser(toUser);
        message.setReadFlag(Convert.toInt(YesOrNoNumber.NO));
        message.setDelByFromUser(Convert.toInt(YesOrNoNumber.NO));
        message.setDelByToUser(Convert.toInt(YesOrNoNumber.NO));
        message.setPopFlag(Convert.toInt(YesOrNoNumber.NO));
        message.setType(DefaultMessage.ID);
        message.setSubType(MessageType.USER_REPLY);

        messageService.save(message);

        return success("回复成功");
    }

    /**
     * 回复框数据加载
     * @return
     */
    @Priv
    @GetMapping("/replyinit/{id}")
    public ApiResponses<Map<String, Object>> replyInit(@PathVariable Long id) {
        Message message = messageService.getById(id);
        Map<String, Object> map = new HashMap<>();
        map.put("toUser", message.getFormUser());
        map.put("subject", "回复:" + HtmlUtil.cleanHtmlTag(message.getSubject()));
        return success(map);
    }

}
